#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<dirent.h>
#include"diyfuction.h"
const char version_real[] = "3.6.1";
struct mod_node
{
    char name[16];
    struct mod_node *next;
}HEAD, *tail = &HEAD, *pretail;
struct mod_checker
{
    char name[128];
    char supported_version[16];
    char remote_file_id[32];
    char supported_version_fix;
}mod_inf;
int version_check(char *version)
{
    int i = 0, j = 0;
    while (version[i]!='\0' && version_real[j]!='\0')
    {
        while (version[i]!='\0' && !digital(version[i])) i++;
        if (version[i]=='\0') break;
        while (version_real[j]!='\0' && !digital(version_real[j])) j++;
        if (version_real[j]=='\0') break;
        if (version[i]=='*') continue;
        if (version[i]!=version_real[j]) return 0;
        i++, j++;
    }
    return 1;
}
void check_and_fix(char *descriptor_content, char *descriptor_path)
{
    char *string_header;
    int i = 0, rewrite_flag = 0;
    memset(&mod_inf,0,sizeof(struct mod_checker));
    if ((string_header=Sunday(descriptor_content, "//"))!=NULL)
    {
        string_header += 2;
        mod_inf.supported_version_fix = 1;
        while(*string_header!='\n'&&*string_header!='\0') mod_inf.name[i++] = *string_header++;
    }
    else
    {
        string_header = Sunday(descriptor_content, "name=\"") + 6;
        while(*string_header!='\"') mod_inf.name[i++] = *string_header++;
    }

    i = 0;
    string_header = Sunday(descriptor_content, "supported_version=\"") + 19;
    while(*string_header!='\"') mod_inf.supported_version[i++] = *string_header++;

    i = 0;
    string_header = Sunday(descriptor_content, "remote_file_id=\"") + 16;
    while(*string_header!='\"') mod_inf.remote_file_id[i++] = *string_header++;


    if ((string_header=Sunday(descriptor_content, "path=\""))!=NULL)
    {
        char *stitch_headr = string_header + 6;
        string_header--;
        while (*stitch_headr!='\0' && *stitch_headr!='\n') stitch_headr++;
        while (*stitch_headr!='\0') *string_header++ = *stitch_headr++;
        *string_header = *stitch_headr;
        rewrite_flag = 1;
    }

    if (!mod_inf.supported_version_fix && !version_check(mod_inf.supported_version))
    {
        fputs("\n\n\n\n",stdout);
        // fputs(descriptor_content,stdout);
        fprintf(stdout,"\n\nmod_name: %s\n",mod_inf.name);
        fprintf(stdout,"\033[1;31m[!!!warning]\033[0msupported_version : %s is not equal to your version\n",mod_inf.supported_version);
        fprintf(stdout,"mod_id: %s\n",mod_inf.remote_file_id);
        system("pause");
        // fprintf(stdout,"Fix Supported Version? (Y or N) [Y: yes;  N: no]  ");
        // char choice;
        // fflush(stdin);
        // fscanf(stdin,"%c",&choice);
        // if (choice=='y' || choice=='Y')
        // {
        //     string_header = Sunday(descriptor_content, "supported_version=\"") + 19;
        //     while (*string_header!='\"')
        //     {
        //         if (digital(*string_header)) *string_header = '*';
        //         string_header++;
        //     }
        //     string_header = descriptor_content + strlen(descriptor_content);
        //     *string_header++ = '\n', *string_header++ = '/', *string_header++ = '/';
        //     i = 0;
        //     while (mod_inf.supported_version[i]!='\0') string_header[i] = mod_inf.supported_version[i], i++;
        //     string_header[i] = '\0';
        //     rewrite_flag = 1;
        // }
    }
    if (rewrite_flag)
    {
        // fputs(descriptor_content, stdout);
        FILE *descriptor_writter = fopen(descriptor_path,"w");
        fputs(descriptor_content, descriptor_writter);
        fclose(descriptor_writter);
    }
}
void add_mod_file(FILE *new_mod_file, char *mod_main_path)
{
    fprintf(new_mod_file,"name=\"%s\"\npath=\"%s\"",mod_inf.name,mod_main_path);
}
void print_mod_name(FILE *mod_file_reader)
{
    char temp[128];
    int i = 0;
    fputc('\t',stdout);
    while(fgets(temp,128,mod_file_reader)!=NULL){
        i = 0;
        if(temp[i++]=='n' && temp[i++]=='a' && temp[i++]=='m' && temp[i++]=='e' && temp[i++]=='=' && temp[i++]=='\"'){
            while (temp[i]!='\"') fputc(temp[i],stdout), i++;
        }
        i = 0;
        if(temp[i++]=='/' && temp[i++]=='/'){
            fputs("<fixed ",stdout);
            while (temp[i]!='\n' && temp[i]!='\0') fputc(temp[i],stdout), i++;
            fputs(">",stdout);
        }
    }
    fputc('\n',stdout);
}
char *fileread(char *content, FILE *filereader)
{
    char temp[128];
    fgets(content,128,filereader);
    while (fgets(temp,128,filereader)!=NULL)
    {
        strcat(content,temp);
    }
    return content;
}
int main()
{
    const char mod_main_rootpath[] = "D:/download/steamCMD/steamapps/workshop/content/281990/";     //必须修改路径
    const char mod_file_rootpath[] = "C:/Users/xxxxx/Documents/Paradox Interactive/Stellaris/mod/"; //必须修改路径
    int i;
    DIR *mainDIR = opendir(mod_main_rootpath);
    DIR *modDIR = opendir(mod_file_rootpath);
    struct dirent *dirp;
    char descriptor_file_content [4096],temp_path[128],mod_main_path[128];
    // get installed mod id list
    while (dirp = readdir(modDIR))
    {
        i = 0;
        while (dirp->d_name[i]!='.' && digital(dirp->d_name[i])) i++;
        if (dirp->d_name[i]!='.' || dirp->d_name[i+1]!= 'm' || dirp->d_name[i+2]!='o' || dirp->d_name[i+3]!='d' || dirp->d_name[i+4]!='\0') continue;
        tail->next = (struct mod_node*)(malloc(sizeof(struct mod_node)));
        tail = tail->next;
        memset(tail->name,0,sizeof(tail->name)),tail->next = NULL, memcpy(tail->name,dirp->d_name,10);
    }
    system("chcp 65001");
    fputs("installed mod list:\n",stdout);
    tail = HEAD.next;
    i = 0;
    while (tail!=NULL)
    {
        memcpy(temp_path,mod_file_rootpath,128);
        strcat(temp_path,tail->name);
        strcat(temp_path,".mod");
        FILE *mod_file_reader = fopen(temp_path,"r");
        print_mod_name(mod_file_reader);
        fclose(mod_file_reader);
        tail = tail->next;
        i++;
    }
    fprintf(stdout,"totally %d mods\n",i);
    // mian function
    while (dirp = readdir(mainDIR))
    {
        i = 0;
        while (dirp->d_name[i] != '\0' && digital(dirp->d_name[i])) i++;
        if (dirp->d_name[i] != '\0') continue;
        // get descriptor.mod path
        strcpy(temp_path, mod_main_rootpath);
        strcat(temp_path, dirp->d_name);
        memcpy(mod_main_path, temp_path, sizeof(char[128]));
        strcat(temp_path,"/descriptor.mod");
        //read descriptor.mod
        FILE *descriptor_file_pointer = fopen(temp_path,"r");
        memset(descriptor_file_content,0,sizeof(descriptor_file_content));
        // fread(descriptor_file_content,1,4096,descriptor_file_pointer);
        fileread(descriptor_file_content,descriptor_file_pointer);
        fclose(descriptor_file_pointer);
        check_and_fix(descriptor_file_content,temp_path);
        // omit installed mod
        i = 0;
        tail = HEAD.next;
        pretail = &HEAD;
        while (tail != NULL)
        {
            if (!strcmp(tail->name,dirp->d_name))
            {
                pretail->next = tail->next;
                struct mod_node *temp = tail;
                tail = tail->next;
                free(temp);
                i = 1;//flag i
                break;
            }
            pretail = tail, tail = tail->next;
        }
        if (i) continue;
        // get id.mod path
        strcpy(temp_path, mod_file_rootpath);
        strcat(temp_path, dirp->d_name);
        strcat(temp_path,".mod");
        FILE *new_mod_file = fopen(temp_path,"w");
        add_mod_file(new_mod_file, mod_main_path);
        fclose(new_mod_file);
    }
    // system("pause");
    return 0;
}